/*
	This file is part of AVRCppLib.

    AVRCppLib is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    AVRCppLib is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with AVRCppLib.  If not, see <http://www.gnu.org/licenses/>.

    Copyright (C) Maxime Lemonnier 2007-2011
 */

#ifndef QUEUE_H_
#define QUEUE_H_
#include "../Utils/CppExtensions.h"
#include "../Utils/BitManipulation.h"
#include "../Utils/Utils.h"
#include "Buffer.h"

/*! Queue datastructure.
 * A fixed sized, array-based queue
 */

template<class ElementType>
class Queue
{

public:
	/*! Constructor
	 * @param capacity the number of elements the \a Queue can contain
	 * @remarks the Queue can only hold \a capacity elements
	 */
	Queue(size_t capacity, ElementType errorSentinel = ElementType());
	
	Queue(Queue<ElementType> &);

	virtual ~Queue();


	void resize(size_t newCapacity);

	const ElementType * inspect();

	/*!
	 * Enqueue an element
	 * @param element the element to enqueue
	 * @return false if the Queue is full
	 */
	bool enQueue(ElementType & element);
	
	/*!
	 * Dequeue an element
	 * @return the element
	 */
	ElementType & deQueue();
	
	ElementType & pop();
	/*!
	 *
	 * @return true if the Queue is full
	 */
	inline bool isFull() const __attribute__((always_inline));
	
	/*!
	 *
	 * @return true if the Queue is empty
	 */
	inline bool isEmpty() const __attribute__((always_inline));
	


	/*!
	 *
	 * @return the number of element contained in the Queue
	 */
	inline size_t numberOfElements() const __attribute__((always_inline));
	
	/*!
	 *
	 * @return the capacity of the Queue
	 */
	inline size_t capacity() const __attribute__((always_inline));


	/*!
	 * Reinitialize the Queue
	 */
	void init();
	
	void clearMemory();

	ElementType & front() const;

	ElementType & tail() const;

	ElementType & operator [] (size_t index) const;

	Queue<ElementType> & operator <<(ElementType & rhs);

	Queue<ElementType> & operator <<(const Buffer<ElementType> & rhs);

	Queue<ElementType> & operator <<(Queue<ElementType> & rhs);

protected:

	ElementType * errorSentinel;

	ElementType * memory;
	size_t size;
	size_t frontIndex;
	size_t tailIndex;
	size_t count;
};



#include "Queue-definitions.h"


#endif /*QUEUE_H_*/
